﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ExcelDna.Integration;
using Excel = Microsoft.Office.Interop.Excel;
using CrystalWind.Example.ExcelDna.CustomerExtentions;
using ExcelDna.Registration;
using ExcelDna.Integration.Rtd;
using System.Threading;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace CrystalWind
{


    class MyTopic : ExcelRtdServer.Topic
    {
        public int Number
        {
            get; set;
        }

        protected internal MyTopic(ExcelRtdServer server, int topicId)
            : base(server, topicId)
        {
        }
    }

    [ComVisible(true)]
    public class MyRtdService : ExcelRtdServer
    {
        private Random _random = new Random();
        private ExcelRtdServer.Topic _topic;

        /// <summary>
        /// 调用rtd公式时,首先执行这个,用于初始化准备,然后excel会产生一个topicId,然后调用CreateTopic
        /// </summary>
        /// <returns></returns>
        protected override bool ServerStart()
        {
            return true;
        }

        /// <summary>
        /// 表示excel启动服务成功,已生成topicId.用于给服务保留关键信息,如topicId.
        /// 这里需要返回给excel一个Topic对象,这个对象让我们通过他来再次刷新公式(调用UpdateValue方法)
        /// 一般我们自定义一个Topic的子类.这样可以传递一些自定义数据
        /// </summary>
        /// <param name="topicId"></param>
        /// <param name="topicInfo"></param>
        /// <returns></returns>
        protected override Topic CreateTopic(int topicId, IList<string> topicInfo)
        {
            return new MyTopic(this, topicId) { Number = _random.Next(1, 10) };
        }

        /// <summary>
        /// 当excel接收到我们返回的Topic对象后,准备好一切后,告诉我们连接成功.
        /// 我们在这个方法的返回值,就作为rtd函数首次的返回值.而且这个方法只会被调用一次
        /// </summary>
        /// <param name="topic"></param>
        /// <param name="topicInfo"></param>
        /// <param name="newValues"></param>
        /// <returns></returns>
        protected override object ConnectData(Topic topic, IList<string> topicInfo, ref bool newValues)
        {
            _topic = topic;

            //Task.Run(delegate
            //{
            //    Thread.Sleep(5000);
            //    _topic.UpdateValue("更新数据");
            //    //_topic.UpdateNotify();
            //});

            return ExcelErrorUtil.ToComError(ExcelError.ExcelErrorNA);;
        }



        protected override void DisconnectData(Topic topic)
        {
            base.DisconnectData(topic);
        }



        protected override void ServerTerminate()
        {
            base.ServerTerminate();
        }
    }

     public static class MyClass
    {
        [ExcelFunction(IsMacroType = true)]
        public static object TestRtdFunc(string v)
        {
            Debug.WriteLine("执行函数1次");
            object rtdValue = XlCall.RTD("CrystalWind.MyRtdService", null,string.Empty);
            
            if (rtdValue is ExcelError)
            {
                return rtdValue;
            }

            return rtdValue.ToString();
        }
    }



}
